package edu.berkeley.cs160.innovationers.shoppersidekick;

import java.util.ArrayList;

import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import edu.berkeley.cs160.innovationers.shoppersidekick.database.MyDB;
import edu.berkeley.cs160.innovationers.shoppersidekick.rpclib.ShopperSidekickProtocol;
import edu.berkeley.cs160.innovationers.shoppersidekick.sync.BluetoothSyncService;
import edu.berkeley.cs160.innovationers.shoppersidekick.sync.JSONRPCMethod;
import edu.berkeley.cs160.innovationers.shoppersidekick.sync.RPCClient;
import android.widget.CompoundButton.OnCheckedChangeListener; 

public class ItemView extends ListActivity {
    private MyListAdapter adapter;
    private ArrayList<Item> myList;
    private TextView ListTitle;
    private ShoppingList myShoppingList;
    private myApp appInfo;
    MyDB localDatabase;
    private ListActivity myself;
    String myShoppingListTitle;
    
    
    //ALL THESE STUFF IS FOR BLUETOOTH STUFF I CREATED FOR CONTINGENCY FOR PRESENTATION, SET DEBUG TO FALSE TO TURN EVERYTHING OFF
    final static boolean DEBUG=false;
    private static final String TAG = "BluetoothChat";
	public static final int MESSAGE_STATE_CHANGE = 1;
	public static final int MESSAGE_DEVICE_NAME = 2;
	public static final int MESSAGE_READ = 4;
    public static final int MESSAGE_WRITE = 3;
	public static final String DEVICE_NAME = "device_name";
    public static final String TOAST = "toast";
	public static final int MESSAGE_TOAST = 5;
    
    // Intent request codes
    private static final int REQUEST_CONNECT_DEVICE = 1;
    private static final int REQUEST_ENABLE_BT = 2;
    
    // Name of the connected device
    private String mConnectedDeviceName = null;
    // Array adapter for the conversation thread
    // String buffer for outgoing messages
    private StringBuffer mOutStringBuffer;
    // Local Bluetooth adapter
    private BluetoothAdapter mBluetoothAdapter = null;
    // Member object for the chat services
    private BluetoothSyncService mSyncService = null;
    
    //BLUETOOTH STUFF ENDS HERE
    
    BackgroundThread backgroundThread;
    
    public class BackgroundThread extends Thread {

    	 boolean running = false;

    	 void setRunning(boolean b){
    	  running = b;
    	 }

    	 @Override
    	 public void run() {
    	  // TODO Auto-generated method stub
    	  //super.run();
    	  while(running){
    	   try {
    	    sleep(8000);
				Log.d(Config.SS_TAG, "Add List Item button called.");
				JSONRPCMethod createList;
				try {
					createList = new JSONRPCMethod.Sync(appInfo.getC2DMUser());
					//createList = new JSONRPCMethod.Sync("nadirabid@gmail.com");
					JSONObject returnValue = RPCClient.execute(createList); 
					RPCClient.resolveSyncData(returnValue, appInfo);
					
					Log.e(Config.SS_TAG, returnValue.getString("success"));
					Log.d(Config.SS_TAG, returnValue.toString());
					
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
    	   } catch (InterruptedException e) {
    	    // TODO Auto-generated catch block
    	    e.printStackTrace();
    	   }
    	   handler.sendMessage(handler.obtainMessage());
    	  }
    	 }

    	}

    
    //do the background sync
    
    
    Handler handler = new Handler(){

    	
    	//DO SYNC HERE
    	 @Override
    	 public void handleMessage(Message msg) {
    	  // TODO Auto-generated method stub
    	  //super.handleMessage(msg);
    		 //CompareData compareData=new CompareData()
    		 	myList.clear();
    		 	myList.addAll(appInfo.findList(appInfo.getListName()).getItemList());
    		 	//localDatabase.insertListData(myShoppingList);
				adapter.notifyDataSetChanged();
				hint();
    	 }

    	};

    	
	
    public class CompareData  {
    		private myApp appInfo;
    		private ArrayList<Member> myMemberList;
    		public CompareData(UserDataFromServer myData, myApp a) {
    			appInfo = a;
    			ShoppingList tempList=myData.getList(myShoppingList.getName());
    			myList=tempList.getItemList();

    			
    		}
    }
    
    
	
	public void RPCAddItemToList(String Member, String ItemName, String ListName, int Qty) {
		
		Log.d(Config.SS_TAG, "Add List Item button called.");
		
		try {
			JSONRPCMethod createList = new JSONRPCMethod.AddListItem(ItemName, ListName, Member, Qty);
			
			JSONObject returnValue = RPCClient.execute(createList);
			
			String ret = returnValue.getString(ShopperSidekickProtocol.AddListItem.RETURN[0]);
			
			Log.d(Config.SS_TAG, "Message Received: ");
		} catch (JSONException e) {
			Log.e(Config.SS_TAG,"We got an error while making the object");
			e.printStackTrace();
		}
		
		Log.d(Config.SS_TAG, "Add List Item button called.");


		
	}
	
	
    public void RPCAddUserToList(String Member, String ListTitle) {
		
		Log.d(Config.SS_TAG, "Add User to List button called.");

		try {
			JSONRPCMethod createList = new JSONRPCMethod.AddUserToList(Member, ListTitle);
			
			JSONObject returnValue = RPCClient.execute(createList);
			
			String ret = returnValue.getString(ShopperSidekickProtocol.AddUserToList.RETURN[0]);
			
			Log.d(Config.SS_TAG, "Message Received: " + ret);
		} catch (JSONException e) {
			Log.e(Config.SS_TAG,"We got an error while making the object");
			e.printStackTrace();
		}
	}

    
    @Override
	public void onActivityResult(int requestCode,int resultCode,final Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch(requestCode) {
			case myApp.newItem: 
				if (resultCode == myApp.addItem) {
					myList.add(0,new Item(data.getCharSequenceExtra("CONTENT").toString(),data.getIntExtra("QTY",0)));
	        		
					localDatabase.insertdiary(data.getCharSequenceExtra("CONTENT").toString(), Integer.toString(data.getIntExtra("QTY",0)), myShoppingListTitle);
					
					adapter.notifyDataSetChanged();
					Thread background = new Thread (new Runnable() {
					   	public void run() {
							RPCAddItemToList(appInfo.getC2DMUser(),data.getCharSequenceExtra("CONTENT").toString(),myShoppingList.getName(),data.getIntExtra("QTY",0));
				    	}
					        
					    }    
					);
					background.start();
				}
			case myApp.editMember:
				if (resultCode == myApp.memberChanged){
					myShoppingList.setMemberList(appInfo.getLocalMemberList());
					for(int i = 0; i < myShoppingList.getMemberList().size(); i++)
						if(!appInfo.getMemberList().contains(myShoppingList.getMemberList().get(i)))
							myShoppingList.getMemberList().remove(i);
				
					//for each member in the list, update list with the member
					Thread background = new Thread (new Runnable() {
					   	public void run() {
							for (int i=0;i<myShoppingList.getMemberList().size();i++) {
								RPCAddUserToList(myShoppingList.getMemberList().get(i).getName(),myShoppingList.getName());
							}
				    	}
					        
					    }    
					);
					background.start();
					
				}
				
				break;
		}
		hint();
	}
    
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK){
        	Intent intent = new Intent();
        	appInfo.getShoppingList().set(appInfo.getPosition(), myShoppingList);
        	setResult(myApp.listChanged,intent);
        	finish();
        }
		return super.onKeyUp(keyCode, event);
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	Bundle extras=getIntent().getExtras();
    	myShoppingListTitle = extras.getString("ShoppingListTitle");
        
		Log.v("test9","before open");
		localDatabase = new MyDB(this);
        localDatabase.open();
		Log.v("test9","after open");

    	
    	super.onCreate(savedInstanceState);
        setContentView(R.layout.itemlist); 
        setTitle("Shopping List: "+myShoppingListTitle);
        myself = this;
        
        appInfo = (myApp) getApplication();
        appInfo.setCurrentActivity(this);

        ListTitle=(TextView)findViewById(R.id.ListTitle);
        ListTitle.setText(myShoppingListTitle);
		Log.v("test9",Integer.toString(appInfo.getPosition()));

        myShoppingList = appInfo.getShoppingList().get(appInfo.getPosition());

        myList = myShoppingList.getItemList();
        appInfo.setListName(myShoppingList.getName());
        Button AddButton=(Button)findViewById(R.id.AddItem);
        
        AddButton.setOnClickListener(new OnClickListener(){
        	public void onClick(View view){
        		Intent myIntent = new Intent(ItemView.this, AddItem.class);
        		startActivityForResult(myIntent, myApp.newItem);   
        	}
        });
        
        Button BackButton = (Button)findViewById(R.id.BackFromItemList);
        BackButton.setOnClickListener(new OnClickListener(){
        	public void onClick(View view){
        		Intent intent = new Intent();
            	appInfo.getShoppingList().set(appInfo.getPosition(), myShoppingList);
            	setResult(myApp.listChanged,intent);
            	localDatabase.close();
            	finish();
        	}
        });
        
        final Button OptionButton = (Button)findViewById(R.id.itemOption);
        OptionButton.setOnClickListener(new OnClickListener(){
        	public void onClick(View view){
        		myself.openOptionsMenu();
        	}
        });
                
        adapter=new MyClickableItemListAdapter(myList,this);
        getListView().setAdapter(adapter);
        
        TextView status = (TextView) findViewById(R.id.Status);
        if(myShoppingList.isShopping()){
			status.setText("Shopping");
		}else{
			status.setText("");
		}
        
        hint();
        
        
        if (DEBUG) {
        	mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if (mBluetoothAdapter == null) {
                Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
            }
        }
        backgroundThread = new BackgroundThread();
        backgroundThread.setRunning(true);
        backgroundThread.start();
    }
    
    
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        if (DEBUG) inflater.inflate(R.menu.btitemmenu, menu); else inflater.inflate(R.menu.itemmenu, menu);
        if(myShoppingList.isShopping())
        	menu.getItem(0).setTitle("End Shopping");
        else
        	menu.getItem(0).setTitle("Go Shopping");
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item){
    	
    	switch (item.getItemId()){
    	case R.id.members:
	    	Intent myIntent = new Intent(ItemView.this, MemberList.class);
			startActivityForResult(myIntent,myApp.editMember);
			appInfo.setCheckList(true);
			appInfo.setLocalMemberList(myShoppingList.getMemberList());
			return true;
    	case R.id.goshopping:
    		myShoppingList.setShopping();
    		TextView status = (TextView) findViewById(R.id.Status);
    		if(item.getTitle().equals("Go Shopping")){
    			status.setText("Shopping");
        		item.setTitle("End Shopping");
    		}else{
    			status.setText("");
        		item.setTitle("Go Shopping");
    		}
    		return true;
    	case R.id.renamelist:
    		Intent intent = new Intent(ItemView.this, RenameList.class);
    		startActivityForResult(intent,myApp.renameList);
    		return true;
    		
    	case R.id.debugc: //start bluetooth client
            // Launch the DeviceListActivity to see devices and do scan
            Intent serverIntent = new Intent(this, DeviceListActivity.class);
            startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
    		return true;
    	case R.id.debugs: //start bluetooth server
    		ensureDiscoverable();
    		return true;
    	}
    	

    		
    	
    	return true;    	
    }
    private class MyClickableItemListAdapter extends MyListAdapter{  
		public MyClickableItemListAdapter(List<Item> myList, Context context) {  
            super(myList,context);  
        } 
		@Override
		public View getView(final int position, View convertView, ViewGroup parent) {
	        LinearLayout ListLayout;
	        final Item myItem=(Item)ContentList.get(position);
	        ListLayout= (LinearLayout) LayoutInflater.from(context).inflate(R.layout.itemlistelement, parent, false);
	        TextView ItemTitle=(TextView) ListLayout.findViewById(R.id.ItemTitle);
	        TextView ItemQty=(TextView) ListLayout.findViewById(R.id.ItemQty);
	        CheckBox ItemCheck=(CheckBox) ListLayout.findViewById(R.id.ItemCheckbox);
	        
	        ItemCheck.setOnCheckedChangeListener(new OnCheckedChangeListener() {
	        	public void onCheckedChanged(CompoundButton buttonView, 
	        			boolean isChecked) { 
	        			// TODO Auto-generated method stub 
	        			if (buttonView.isChecked()) { 

	        			} 
	        	}
	        }
	        	);
	        ImageView DelButton=(ImageView) ListLayout.findViewById(R.id.DelImage);
	        DelButton.setOnClickListener(new OnClickListener(){
	        	public void onClick(View view){
	        		ContentList.remove(myItem);
	        		
	        		localDatabase.deletediary(myItem.getName(), myShoppingListTitle);
	        		
	        		adapter.notifyDataSetChanged();
	        	}
	        });
	        ItemTitle.setText(myItem.getName());
	        
	        String TempResult="";
	        if (myItem.getQty()<10) TempResult="0"+String.valueOf(myItem.getQty()); else TempResult=String.valueOf(myItem.getQty()); 
	        ItemQty.setText("x"+TempResult);
	        
	        return ListLayout;
		}
    }
    
    private void hint(){
    	TextView temp = (TextView) findViewById(R.id.itemview_hint);
    	
        if(myList.size() < 1){
        	temp.setText("Use 'add' to create a new shopping item and use 'option' to find more options");
        	temp.setTextSize(15);
        	temp.setTextColor(Color.GRAY);
        }else{
        	temp.setText("");
        }
    }
    
    
    
    private void setupSync() {
        Log.d(TAG, "setupChat()");

        // Initialize the BluetoothChatService to perform bluetooth connections
        mSyncService = new BluetoothSyncService(this, mHandler);

        // Initialize the buffer for outgoing messages
        mOutStringBuffer = new StringBuffer("");
    }
    
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MESSAGE_STATE_CHANGE:
                if(DEBUG) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
                switch (msg.arg1) {
                case BluetoothSyncService.STATE_CONNECTED:

                    break;
                case BluetoothSyncService.STATE_CONNECTING:

                    break;
                case BluetoothSyncService.STATE_LISTEN:
                case BluetoothSyncService.STATE_NONE:

                    break;
                }
                break;
            case MESSAGE_WRITE:
                byte[] writeBuf = (byte[]) msg.obj;
                // construct a string from the buffer
                String writeMessage = new String(writeBuf);

                break;
            case MESSAGE_READ:
                byte[] readBuf = (byte[]) msg.obj;
                // construct a string from the valid bytes in the buffer
                String readMessage = new String(readBuf, 0, msg.arg1);

                break;
            case MESSAGE_DEVICE_NAME:
                // save the connected device's name
                mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
                Toast.makeText(getApplicationContext(), "Connected to "
                               + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
                break;
            case MESSAGE_TOAST:
                Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
                               Toast.LENGTH_SHORT).show();
                break;
            }
        }
    };
    
    @Override
    public void onStart() {
        super.onStart();
        if(DEBUG) {Log.e(TAG, "++ ON START ++");

        // If BT is not on, request that it be enabled.
        // setupChat() will then be called during onActivityResult
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
        // Otherwise, setup the chat session
        } else {
            if (mSyncService == null) setupSync();
        }
        }
    }

    public void onStop() {
    	super.onStop();
    	backgroundThread.setRunning(false);
    }
    @Override
    public synchronized void onResume() {
        super.onResume();
        if(DEBUG) {Log.e(TAG, "+ ON RESUME +");

        // Performing this check in onResume() covers the case in which BT was
        // not enabled during onStart(), so we were paused to enable it...
        // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
        if (mSyncService != null) {
            // Only if the state is STATE_NONE, do we know that we haven't started already
            if (mSyncService.getState() == BluetoothSyncService.STATE_NONE) {
              // Start the Bluetooth chat services
              mSyncService.start();
            }
        }
        }
    }
    
    private void sendMessage(String message) {
        // Check that we're actually connected before trying anything
        if (mSyncService.getState() != BluetoothSyncService.STATE_CONNECTED) {
            Toast.makeText(this, "Not connected", Toast.LENGTH_SHORT).show();
            return;
        }

        // Check that there's actually something to send
        if (message.length() > 0) {
            // Get the message bytes and tell the BluetoothChatService to write
            byte[] send = message.getBytes();
            mSyncService.write(send);

            // Reset out string buffer to zero and clear the edit text field
            mOutStringBuffer.setLength(0);
        }
    }
    
    private void ensureDiscoverable() {
        if(DEBUG) Log.d(TAG, "ensure discoverable");
        if (mBluetoothAdapter.getScanMode() !=
            BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
            startActivity(discoverableIntent);
        }
    }

}